package cn.com.wxd.common;

import java.lang.reflect.*;
import java.util.HashMap;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.Iterator;

/**
 * <p>Title: 反射类</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2007</p>
 * <p>Company: Amumu管理平台</p>
 * @author not attributable
 * @version 1.0
 */
public class ReflectionUtil {
  public ReflectionUtil() {
  }
  /**
   * 得到某个对象的公共属性
   *
   * @param owner 类对象
   * @param fieldName 变量名
   * @return 该属性对象
   * @throws Exception
   *
   */
  public Object getProperty(Object owner, String fieldName) throws Exception {
      
      Class ownerClass = owner.getClass();
      Field field = ownerClass.getField(fieldName);
      Object property = field.get(owner);

      return property;
  }

  /**
   * 得到某类的静态公共属性
   *
   * @param className   类名
   * @param fieldName   属性名
   * @return 该属性对象
   * @throws Exception
   */
  public Object getStaticProperty(String className, String fieldName) throws Exception {
      Class ownerClass = Class.forName(className);
      Field field = ownerClass.getField(fieldName);
      Object property = field.get(ownerClass);

      return property;
  }
  /**
   * 执行某对象方法
   *
   * @param owner 对象
   * @param methodName 方法名
   * @param args  参数
   * @return 方法返回值
   * @throws Exception
   */
  public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
      Class ownerClass = owner.getClass();
      Class[] argsClass = null;

      if (args!=null) {
        argsClass = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
          argsClass[i] = args[i].getClass();
        }
      }

	Method method = ownerClass.getMethod(methodName, argsClass);

      return method.invoke(owner, args);
  }
  /**
   * 执行某类的静态方法
   * @param className  类名
   * @param methodName 方法名
   * @param args 参数数组
   * @return 执行方法返回的结果
   * @throws Exception
   */
  public Object invokeStaticMethod(String className, String methodName, Object[] args) throws Exception {
    Class newClass = Class.forName(className);
    Class[] argsClass = null;
    if (args != null) {
      argsClass = new Class[args.length];
      for (int i = 0; i < args.length; i++) {
        argsClass[i] = args[i].getClass();
      }
    }

    Method method = newClass.getMethod(methodName, argsClass);

    return method.invoke(null, args);
  }
  /**
   * 新建实例
   * @param className 类名
   * @param args 构造函数的参数
   * @return 新建的实例
   * @throws Exception
   */
  public Object newInstance(String className, Object[] args) throws Exception {
    Class newClass = Class.forName(className);
    Class[] argsClass = null;

    if (args != null) {
      argsClass = new Class[args.length];
      for (int i = 0; i < args.length; i++) {
        argsClass[i] = args[i].getClass();
      }
    }
    Constructor cons = newClass.getConstructor(argsClass);

    return cons.newInstance(args);
  }
  /**
   * 是不是某个类的实例
   * @param obj 实例
   * @param cls 类
   * @return 如果 obj 是此类的实例，则返回 true
   */
  public boolean isInstance(Object obj, Class cls) {
      return cls.isInstance(obj);
  }
  /**
   * 得到数组中的某个元素
   * @param array 数组
   * @param index 索引
   * @return 返回指定数组对象中索引组件的值
   */
  public Object getByArray(Object array, int index) {
      return Array.get(array,index);
  }
  /**
   * 设置数组的某个元素
   * @param array 数组
   * @param index 索引
   * @param obj 对象
   */
  public void setArray(Object array,int index,Object obj) {
    Array.set(array,index,obj);
  }
  /**
   * 实例化某个类的数组
   * @param className 类名
   * @param length 长度
   * @return 对象数组
   * @throws Exception
   */
  public Object newArray(String className,int length) throws Exception {
    Class newClass = getClassforName(className);
    return Array.newInstance(newClass,length);
  }
  /**
   * 实例化一个多维数组
   * @param className 类名
   * @param dimensions 维度
   * @return 多维数组
   * @throws Exception
   */
  public Object newArrays(String className,int[] dimensions) throws Exception {
    Class newClass = getClassforName(className);
    return Array.newInstance(newClass,dimensions);
  }
  /**
   * 转换某个对象为另一种类型的对象
   * @param newType 新对象
   * @param value 对象
   * @return 对象
   * @throws Exception
   */
  public Object convertType(String newType, Object value) throws Exception {
    if (value==null) return value;
    // try call constructor
    Class type = Class.forName(newType);
    Class[] types = new Class[]{type};
    Constructor constructor = type.getConstructor(types);
    Object[] arguments = { value };

    return constructor.newInstance(arguments);
  }
  // 返回类
  private Class getClassforName(String className) throws Exception {
    Class newClass = null;
    if (className.equals("byte"))
      newClass = byte.class;
    else if (className.equals("short"))
      newClass = short.class;
    else if (className.equals("int"))
      newClass = int.class;
    else if (className.equals("long"))
      newClass = long.class;
    else if (className.equals("char"))
      newClass = char.class;
    else if (className.equals("float"))
      newClass = float.class;
    else if (className.equals("double"))
      newClass = double.class;
    else if (className.equals("boolean"))
      newClass = boolean.class;
    else if (className.equals("void"))
      newClass = void.class;
    else
      newClass = Class.forName(className);

    return newClass;
  }
  /**
   * 取Getter/Setter对象的内容为HashMap
   * @param obj Getter/Setter对象
   * @return 成员变量的值对
   * @throws Exception
   */
  public static HashMap getFieldMap(Object obj) throws Exception {
    HashMap map = new HashMap();
    BeanInfo bi = Introspector.getBeanInfo(obj.getClass(), Object.class);
    PropertyDescriptor[] pd = bi.getPropertyDescriptors();
    Class c;
    //演示如何get
    for (int i = 0; i < pd.length; i++) {
      c = pd[i].getPropertyType();
      Object o = pd[i].getReadMethod().invoke(obj, null);
      if (c.isPrimitive()) {
        map.put(pd[i].getName().toLowerCase(),o.toString());
        continue;
      }
      if (c==String.class)
        map.put(pd[i].getName().toLowerCase(),o);
    }

    return map;
  }
  /**
   * 根据HashMap中的内容初始化一个Getter/Setter对象
   * @param map 内容，键号必须为大写
   * @param className 类
   * @return 初始化的对象
   * @throws Exception
   */
  public static Object newInstanceByMap(HashMap map,String className) throws Exception {
    Class newClass = Class.forName(className);
    Object obj = newClass.newInstance();
    if (map==null) return obj;
    BeanInfo bi = Introspector.getBeanInfo(obj.getClass(), Object.class);
    PropertyDescriptor[] pd = bi.getPropertyDescriptors();
    String key;

    for (int i = 0; i < pd.length; i++) {
      key = getKey(map,pd[i].getName());
      if (key==null)
        continue;
      String v = (String) map.get(key);
      if (v == null || v.equals(""))
        continue;
      Class type = pd[i].getPropertyType();
      if (type == int.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Integer(v)});
      else if (type == double.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Double(v)});
      else if (type == float.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Float(v)});
      else if (type==byte.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Byte(v)});
      else if (type==long.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Long(v)});
      else if (type==short.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Short(v)});
      else if (type==boolean.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Boolean(v)});
      else if (type==char.class)
        pd[i].getWriteMethod().invoke(obj, new Object[] {new Character(v.charAt(0))});
      else
        pd[i].getWriteMethod().invoke(obj, new Object[] {v});
    }

    return obj;
  }
  // 根据方法号取实际的键值
  private static String getKey(HashMap map,String field) {
    Iterator it = map.keySet().iterator();
    while (it.hasNext()) {
      String key = (String)it.next();
      if (key.equalsIgnoreCase(field)) return key;
    }

    return null;
  }
}
